package org.hishenframework.tool.codegenerate;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.Id;

import org.hishen.example.entity.mall.Category;
import org.hishen.example.entity.system.Test;
import org.hishenframework.tool.EntityUtils;
import org.hishenframework.tool.codegenerate.method.ElTemplateMethodModelEx;
import org.hishenframework.tool.codegenerate.method.LabelTemplateMethodModelEx;
import org.hishenframework.tool.codegenerate.method.PluralizeTemplateMethodModelEx;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class CodeBuilder {
	/** 项目路径 */
	private final static String PROJECT_PATH;
	/** 模板路径 */
	private final static String TEMPLATE_PATH;
	/** 源码路径 */
	private final static String SOURCE_PATH;
	/** jsp路径 */
	private final static String PAGE_PATH;
	
	static {
		String projectPath = CodeBuilder.class.getClass().getResource("/").getPath();
		try {
			projectPath = new String(projectPath.getBytes(), "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		PROJECT_PATH = projectPath;
		TEMPLATE_PATH = PROJECT_PATH + "template";
		SOURCE_PATH = PROJECT_PATH.replaceFirst("/target/classes", "") + "src/main/java";
		PAGE_PATH = PROJECT_PATH.replaceFirst("/target/classes", "") + "src/main/webapp/WEB-INF/page/app/admin";
	}
	
	public static void builder(Class<?> entityClass) throws IOException {
		//类型名称
		String entityClassName = entityClass.getSimpleName();
		//类型变量名称
		String entityVarName = EntityUtils.firstLetterLowercase(entityClassName);
		//包名称
		String entityPackage = entityClass.getPackage().getName();
		
		entityPackage.indexOf(entityClassName);
		
		//根节点
		Map<String, Object> root = new HashMap<String, Object>();
		//设置自定义函数
		//首字母小写
//		root.put("fn_fll", new FirstLetterLowercaseTemplateMethodModelEx());
		//成复数
		root.put("fn_pluralize", new PluralizeTemplateMethodModelEx());
		//获取实体标签
		root.put("fn_label", new LabelTemplateMethodModelEx());
		//输出${var}
		root.put("fn_el", new ElTemplateMethodModelEx());
		//可执行静态方法
		root.put("statics", BeansWrapper.getDefaultInstance().getStaticModels());
		root.put("entityClass", entityClass);
		
		root.put("IdClass", Id.class);
		root.put("entityClassName", entityClassName);
		root.put("entityVarName", entityVarName);
		root.put("serviceClassName", entityClassName + "Service");
		root.put("serviceVarName", entityVarName + "Service");
		root.put("controllerClassName", entityClassName + "Controller");
//		root.put("entityVarName", entityVarName + "Controller");

		root.put("entityPackageName", entityPackage);
		root.put("servicePackageName", entityPackage.replaceFirst("entity", "service.admin"));
		root.put("controllerPackageName", entityPackage.replaceFirst("entity", "web.admin"));
		root.put("urlPath", entityClass.getName().replaceFirst(".*\\.entity", "").replaceAll("\\.", "/").toLowerCase());
		
		//获得模板路径
		//创建freemarker 配置
		Configuration cfg = new Configuration();
		cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
		cfg.setObjectWrapper(new DefaultObjectWrapper());
		String path = entityPackage.replaceAll("\\.", "/");
		String servicePath = SOURCE_PATH + "/" + path.replaceFirst("entity", "service/admin") + "/" + entityClassName + "Service.java";;
		String controllerPath = SOURCE_PATH + "/" + path.replaceFirst("entity", "web/admin") + "/" + entityClassName + "Controller.java";
		String pagePath = PAGE_PATH + path.replaceFirst("^(.*entity)", "") + "/" + entityClassName.toLowerCase();
		//输出文件
		outPut(cfg.getTemplate("service.java.ftl"), root, servicePath);
		outPut(cfg.getTemplate("controller.java.ftl"), root, controllerPath);
		outPut(cfg.getTemplate("page/list.jsp.ftl"), root, pagePath + "/list.jsp");
		outPut(cfg.getTemplate("page/create.jsp.ftl"), root, pagePath + "/create.jsp");
		outPut(cfg.getTemplate("page/edit.jsp.ftl"), root, pagePath + "/edit.jsp");
		outPut(cfg.getTemplate("page/form.jsp.ftl"), root, pagePath + "/form.jsp");
	}
	
	private static void outPut(Template temp, Map<String, Object> root, String path) {
		File file = new File(path);
		file.getParentFile().mkdirs();
		try {
			Writer out = new OutputStreamWriter(new FileOutputStream(file));
			temp.process(root, out);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws IOException, TemplateException {
		//读取模板
		//根据EntityClass生成类
		//service
		//controller
		//jsp
		// 创建根哈希表 
		builder(Test.class);
	}
}
